package com.boot.config;

import com.boot.filter.LoginFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @EnableWebSecurity:SpringSecurity的配置类 开启SpringSecurity【自带大量过滤器链:责任链模式】
 */
@Configuration //
@EnableWebSecurity //5.x中@EnableWebSecurity自带@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        //authorizeHttpRequests:针对http请求进行授权,第一个过滤器
        http.authorizeHttpRequests(authorizeHttpRequests -> authorizeHttpRequests
                        //角色控制系统   (其实就是权限控制系统加前缀ROLE_)
//                .requestMatchers("/admin/api").hasRole("admin")//必须有admin才能访问
//                .requestMatchers("/user/api").hasAnyRole("admin", "user")//必须有admin,user才能访问
                        //权限控制系统
                        //实际开发只用此模式,角色由数据控制
                        .requestMatchers("/admin/api").hasAuthority("admin:api")//必须有admin:api才能访问
                        .requestMatchers("/user/api").hasAnyAuthority("admin:api", "user:api")//必须有admin,user才能访问

                        //ant匹配模式
                        .requestMatchers("/adminA/**").hasAuthority("admin:api")

                        //login登录页面需要匿名访问
                        // permitAlL:具有所有权限 也就可以匿名可以访问
                        .requestMatchers("/app/api").permitAll()
                        .requestMatchers("/login").permitAll()
                        //anyRequest:任何请求 所有请求
                        //authenticated:认证[登录]
                        .anyRequest().authenticated()
        );
        //无权限处理
        http.exceptionHandling(e -> e.accessDeniedPage("/noAuth"));

        //登录过滤器
        http.formLogin(formLogin -> formLogin
                //loginPage:登录页面
                .loginPage("/login").permitAll()
                //登录接口 过滤器
                .loginProcessingUrl("/login")
                //登录后的跳转
                .defaultSuccessUrl("/index")
        );

        //配管自定义登录过滤器

        http.addFilterAt(new LoginFilter(), UsernamePasswordAuthenticationFilter.class);

        //跨域漏洞防御:关闭
//        http.csrf(crsf -> crsf.disable());
        http.csrf(AbstractHttpConfigurer::disable);

        //退出
        http.logout(logout -> logout.invalidateHttpSession(true));

        return http.build();
    }

    //如果一定要使用角色,并且自己实现UserDetailsService那么记得角色是权限前   加 ROLE_ 的前缀
//    @Bean
//    public UserDetailsService userDetailsService() {
//        UserDetails user1 = User.withUsername("admin").password("123456").roles("admin", "user").authorities("admin:api").build();
//        UserDetails user2 = User.withUsername("user").password("123456").roles("user").build();
//        return new InMemoryUserDetailsManager(user1, user2);
//    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }
}
